package com.sanshengshui.im.server;

import com.sanshengshui.im.codec.PacketCodecHandler;
import com.sanshengshui.im.codec.Spliter;
import com.sanshengshui.im.handler.IMIdleStateHandler;
import com.sanshengshui.im.server.handler.AuthHandler;
import com.sanshengshui.im.server.handler.HeartBeatRequestHandler;
import com.sanshengshui.im.server.handler.IMHandler;
import com.sanshengshui.im.server.handler.LoginRequestHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.util.Date;

public class NettyServer {

    private static final int PORT = 8000;

    public static void main(String[] args) {
        NioEventLoopGroup boosGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        final ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap
                .group(boosGroup, workerGroup)//设置两个线程组
                .channel(NioServerSocketChannel.class)//使用NiOS噢创可贴Channel作为服务器的通道实现
                .option(ChannelOption.SO_BACKLOG, 1024)//设置线程队列得到连接个数
                .childOption(ChannelOption.SO_KEEPALIVE, true)//设置保持活动连接状态
                .childOption(ChannelOption.TCP_NODELAY, true)//
                .handler(new LoggingHandler(LogLevel.INFO))//
                .childHandler(new ChannelInitializer<NioSocketChannel>() {//创建一个通道测试对象(匿名对象)
                    protected void initChannel(NioSocketChannel ch) {//给pipeline 设置处理
                        // 空闲检测
                        ch.pipeline().addLast(new IMIdleStateHandler());
                        ch.pipeline().addLast(new Spliter());
                        ch.pipeline().addLast(PacketCodecHandler.INSTANCE);
                        ch.pipeline().addLast(LoginRequestHandler.INSTANCE);
                        ch.pipeline().addLast(HeartBeatRequestHandler.INSTANCE);
                        ch.pipeline().addLast(AuthHandler.INSTANCE);
                        ch.pipeline().addLast(IMHandler.INSTANCE);
                    }
                }); //给我们的workergroup 的enventLoop 对应的管道设置处理


        bind(serverBootstrap, PORT);
    }

    private static void bind(final ServerBootstrap serverBootstrap, final int port) {
        serverBootstrap.bind(port).addListener(future -> {//绑定一个端口 生成一个ChannelFuture对象
            if (future.isSuccess()) {
                System.out.println(new Date() + ": 端口[" + port + "]绑定成功!");
            } else {
                System.err.println("端口[" + port + "]绑定失败!");
            }
        });
    }
}
